package com.niu.wm.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.niu.wm.core.error.GlobalErrorCode;
import com.niu.wm.core.error.BizException;
import com.niu.wm.dao.mapper.UserMapper;
import com.niu.wm.model.User;
import com.niu.wm.service.BaseService;
import com.niu.wm.service.UserService;

@Service
public class UserServiceImpl extends BaseService implements UserService {
	private Map<Long,User> cacheById = null;
	private Map<String,User> cacheByAccount = null;
	
	
	@Autowired 
	private UserMapper userMapper;
	
    @Autowired
    private PasswordEncoder    pwdEncoder;
    
    @Override
   	public void refrechCache(){
    	cacheById = null;
    	cacheByAccount = null;
    }
    
	private void refreshCache(Long id, String account) {
		if (cacheById == null) {
			cacheById = new HashMap<Long, User>();
			cacheByAccount = new HashMap<String, User>();
		}

		User user = null;
		if (null != id)
			user = userMapper.selectById(id);
		else
			user = userMapper.selectByAccount(account);
		

		if (null != user) {
			cacheById.put(user.getId(), user);
			cacheByAccount.put(user.getAccount(), user);
		}
	}
	
	@Override
    public String getUserName(Long id){
    	return load(id).getName();
    }
    
	@Override
    public User load(Long id){
    	return load(id, null);
    }
    
	@Override
	public User loadByAccount(String account) {
		return load(null, account);
	}

	private User load(Long id, String account) {
		User user = null;
		if (null != cacheById) {
			if (null != id)
				user = cacheById.get(id);
			else
				user = cacheByAccount.get(account);
		}

		if (user == null) {
			refreshCache(id, account);
			if (null != id)
				user = cacheById.get(id);
			else
				user = cacheByAccount.get(account);
		}

		return user;
	}

    public boolean add(User user){
    	// 用户的验证应该放到这里来，否则有安全问题
        User u1 = userMapper.selectByAccount(user.getAccount());
        if (u1 != null) {
            //throw new BizException(GlobalErrorCode.USER_EXIST, "用户名已被占用，请重新输入！");
        	return false;
        }
        if(StringUtils.isEmpty(user.getPassword()))
        	user.setPassword("meishi2016");

        String pwd = pwdEncoder.encode(user.getPassword());
        user.setPassword(pwd);

        int result = userMapper.insert(user);
        
        refreshCache(user.getId(), null);
        
        return result > 0;
    }

    public int update(User user){    	
    	int count = userMapper.update(user);
        refreshCache(user.getId(), null);
        
        return count;
    }

    public boolean changePwd(Long userId, String password){
        boolean changed = false;
        
        String newPwd = pwdEncoder.encode(password);
        changed = userMapper.changePwd(userId, newPwd) > 0;
        
        refreshCache(userId, null);

        return changed;
    }

    public boolean isRegistered(String loginname){
        return userMapper.countRegistered(loginname) > 0;
    }

    /**
     * 根据用户名获取用户信息-- spring-security 接口需要的方法
     */
    public User loadUserByUsername(String account) throws UsernameNotFoundException{    	    	
    	User user = userMapper.selectByAccount(account);
    	if(user == null)
    		throw new UsernameNotFoundException("user not found");
   
    	
    	return user;
    }

    /**
     * 用户登录
     * @param userName
     * @param userPwd
     * @return
     */
    @Override
    public User login(String account, String userPwd){
    	User u = userMapper.selectByAccount(account);

        if (u == null) {
            getLogger().debug("u:{} not exist", account);
            throw new BizException(GlobalErrorCode.USER_NOT_EXIST, "valid.user.notExist.message");
        }

        if (!pwdEncoder.matches(userPwd, u.getPassword())) {
            getLogger().debug("userPwd:{} password.invalid", userPwd);
            throw new BizException(GlobalErrorCode.PASSWORD_INVALID, "password.invalid");
        }
        return u;
    }
        
    @Override
    public void loginLog(User user, String fromIP){
    	userMapper.addLoginLog(user.getId(), user.getName(), fromIP);
    }

}
